import { ref, unref, isRef, computed, UnwrapRef, MaybeRef } from 'vue'
import { useAsync } from '@/hooks/web/use-async'
import { isObject } from '@/utils/is'

/**
 * 分页请求
 * @param listQuery
 * @param apiFunc
 */
export const usePagingQuery = <T, D>(listQuery: MaybeRef<T>, apiFunc: Fn) => {
  const { run, stat } = useAsync<IListResponse<D[]>>()

  // 默认参数
  const pageQuery = ref<ISystemPagination>({
    size: 10,
    current: 1
  })
  // 重置时使用的参数
  const resetQuery = ref({
    current: 1
  })
  // 数据总数
  const totalCount = ref(0)

  // table数据
  const tableData = ref<D[]>([])
  // 加载状态
  const loading = computed(() => {
    return stat.value === 'loading'
  })

  /**
   * 获取分页列表
   */
  const getPagingList = async (): Promise<UnwrapRef<D[]>> => {
    if (typeof apiFunc !== 'function') {
      return Promise.reject(new Error('apiFunc must be a function'))
    }
    // 调用接口函数
    const api = (): Promise<IApiResponseData<IListResponse<UnwrapRef<D[]>>>> => {
      const inputQuery = isObject(listQuery) ? (isRef(listQuery) ? listQuery.value : listQuery) : {}
      // 合并传入参数
      const query = { ...unref(pageQuery), ...inputQuery }
      // 调用接口
      return apiFunc(query)
    }
    try {
      const backData = await run(api())
      // 更新分页信息
      const { current, count, data } = backData
      pageQuery.value.current = resetQuery.value.current = current
      totalCount.value = count
      tableData.value = data || []
      return data || []
    } catch (e) {
      pageQuery.value.current = resetQuery.value.current
      throw e
    }
  }

  /**
   * 查询
   * 如果不对返回的 tableData 做处理，可以直接用这个查询方法，并且直接使用 tableData 渲染数据
   * 如果需要对返回的 tableData 做处理，比如需要对数据进行格式化，则需要调用自己的查询方法
   */
  const handleSearch = async () => {
    try {
      pageQuery.value.current = 1
      await getPagingList()
    } catch (e) {
      console.log(e)
    }
  }

  return {
    tableData,
    stat,
    totalCount,
    loading,
    pageQuery,
    getPagingList,
    handleSearch,
    handlePageSizeChange: handleSearch
  }
}
